﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using IrendilDLL.Database;
using System.Data;
using IrendilDLL;
using System.Data.SqlClient;
using System.IO;
using System.Net.NetworkInformation;
using IrendilDLL.PageControls;
using System.Management;
using IrendilDLL.utilities;

namespace IrendilDLL.PageControls
{
    /// <summary>
    /// Classe di controllo della pagina Disk
    /// </summary>
    public class DiskControl
    {
        /// <summary>
        /// Costruttore di default
        /// </summary>
        public DiskControl()
        {
            // Procedo solo se é correttamente inizializzata la variabile di sessione
            installationGUID = (String)HttpContext.Current.Session["installationGUID"];

            // Ottengo la stringa di connessione al db
            localSqlServerStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
        }


        /// <summary>
        /// Guid installazione di riferimento
        /// </summary>
        String installationGUID = null;
        /// <summary>
        /// Stringa di connessione al db
        /// </summary>
        string localSqlServerStr = null;
        /// <summary>
        /// Riferimento al file di log
        /// </summary>
        TextWriter logFile;
        ///// <summary>
        ///// Soglia di warning
        ///// </summary>
        //private float warningThreshold = 10;
        ///// <summary>
        ///// Soglia di alert
        ///// </summary>
        //private float alertThreshold = 5;


        ///// <summary>
        ///// properties di WarningThreshold
        ///// </summary>
        //public float WarningThreshold
        //{
        //    get { return warningThreshold; }
        //    set { warningThreshold = value; }
        //}
        ///// <summary>
        ///// properties di alertThreshold
        ///// </summary>
        //public float AlertThreshold
        //{
        //    get { return alertThreshold; }
        //    set { warningThreshold = value; }
        //}


        /// <summary>
        /// Metodo che torna un datatable contenente i risultati del test dei dischi da presentare a monitor
        /// </summary>
        /// <returns></returns>
        public DataTable getDisksDT(String hostSelected, DateTime fromDate, DateTime toDate)
        {
            // Prelevo i dati da DB
            try
            {
                DataBaseManager dbManager = new DataBaseManager(localSqlServerStr);

                // Imposto i parametri per la QUERY
                SqlParameter[] parameters = new SqlParameter[4];

                parameters[0] = new SqlParameter("@GUIDInstallation", installationGUID);
                // Nel caso non sia selezionato nulla non filtro altrimenti...
                if (hostSelected == null || hostSelected == "")
                    parameters[1] = new SqlParameter("@GUIDHost", "%");
                else
                    parameters[1] = new SqlParameter("@GUIDHost", hostSelected.ToString().ToUpper());
                // Le date devono essere sempre impostate
                parameters[2] = new SqlParameter("@fromDate", fromDate);
                parameters[3] = new SqlParameter("@toDate", toDate);

                // Apro la transazione, eseguo la store e la chiudo
                dbManager.OpenTransaction();
                DataSet eventDs = dbManager.EseguiStored("sp_getDisks", parameters);
                dbManager.CloseTransaction();

                // Se la query torna dati continuo
                if (eventDs != null && eventDs.Tables.Count > 0)
                {
                    // Prelevo il dataTable con i dati
                    DataTable dt = eventDs.Tables[0];

                    // Sostituisto nel datatable per comodità i lettura i valori
                    // in byte con i corrispettivi in gigabyte
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        // Controllo che non sia zero
                        if (Convert.ToSingle(dt.Rows[i]["Size"]) > 1)
                            dt.Rows[i]["Size"] = ((ConvertBytesToGigabytes(Convert.ToDouble(dt.Rows[i]["Size"]))).ToString("F2"));

                        // Controllo che non sia zero
                        if (Convert.ToSingle(dt.Rows[i]["FreeSpace"]) > 1)
                            dt.Rows[i]["FreeSpace"] = ((ConvertBytesToGigabytes(Convert.ToDouble(dt.Rows[i]["FreeSpace"]))).ToString("F2")); 

                        // Controllo che non sia zero
                        if (dt.Rows[i]["FreeSpacePerc"] != DBNull.Value)
                            dt.Rows[i]["FreeSpacePerc"] = ((Convert.ToSingle(dt.Rows[i]["FreeSpacePerc"])).ToString("F2"));

                        

                    }

                    return dt;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                // Istanzio la classe di gestione dell'errore
                LogErrors logError = new LogErrors();
                // Scrivo l'errore su file
                logError.WriteLogToFile(ex.Source+": "+ex.Message);
                // Rimbalzo l'eccezione per la visualizzazione su gui
                throw ex;
            }
        }

        /// <summary>
        /// Metodo che dice se un disco é tra quelli "chiusi" oppure no
        /// </summary>
        /// <param name="GUIDHost">Host di riferimento</param>
        /// <param name="volume">Volume di riferimento</param>
        /// <returns>True in caso sia disco chiuso</returns>
        public bool isClosedDisks(Guid GUIDHost, String volume)
        {
            // Prelevo i dati da DB
            try
            {
                DataBaseManager dbManager = new DataBaseManager(localSqlServerStr);

                // Imposto i parametri per la QUERY
                SqlParameter[] parameters = new SqlParameter[2];

                parameters[0] = new SqlParameter("@GUIDHost", GUIDHost);
                parameters[1] = new SqlParameter("@Volume", volume);

                // Apro la transazione, eseguo la store e la chiudo
                dbManager.OpenTransaction();
                DataSet chackClosedDiskDs = dbManager.EseguiStored("sp_checkClosedDisk", parameters);
                dbManager.CloseTransaction();

                // Se la query torna dati continuo
                if (chackClosedDiskDs != null && chackClosedDiskDs.Tables.Count > 0)
                {
                    // Prelevo il dataTable con i dati
                    DataTable dt = chackClosedDiskDs.Tables[0];
                    int diskOccurence = Convert.ToInt16(dt.Rows[0]["DiskOccurrence"]);
                    // Se trovo un disco nella "blacklist" vuol dire che non é da controllare
                    if (diskOccurence > 0)
                        return true;
                    else
                        return false;
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                // Istanzio la classe di gestione dell'errore
                LogErrors logError = new LogErrors();
                // Scrivo l'errore su file
                logError.WriteLogToFile(ex.Source+": "+ex.Message);
                // Rimbalzo l'eccezione per la visualizzazione su gui
                throw ex;
            }
        }



        /// <summary>
        /// Metodo ad uso interno per la conversione tra byte e Megabyte
        /// </summary>
        /// <param name="bytes">byte</param>
        /// <returns>MB</returns>
        private double ConvertBytesToMegabytes(double bytes)
        {
            return (bytes / 1024f) / 1024f;
        }

        /// <summary>
        /// Metodo ad uso interno per la conversione tra byte e Megabyte
        /// </summary>
        /// <param name="bytes">byte</param>
        /// <returns>MB</returns>
        private double ConvertBytesToGigabytes(double bytes)
        {
            return ((bytes / 1024f) / 1024f) / 1024f;
        }
    }
}
